<?php

namespace app\admin\model;

use app\admin\model\cms\Channels;
use app\common\model\MoneyLog;
use app\common\model\ScoreLog;
use DateTime;
use think\Db;
use think\Model;
use traits\model\SoftDelete;

class User extends Model
{

    use SoftDelete;

    // 表名
    protected $name = 'user';
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = 'int';
    // 定义时间戳字段名
    protected $createTime = 'createtime';
    protected $updateTime = 'updatetime';
    protected $deleteTime = 'deletetime';
    // 追加属性
    protected $append = [
        'prevtime_text',
        'logintime_text',
        'jointime_text',
        'avatar_obs',
    ];

    public function getOriginData()
    {
        return $this->origin;
    }

    protected static function init()
    {
        self::beforeInsert(function ($row) {
            $changed = $row->getChangedData();
            //如果有修改密码
            if (isset($changed['password'])) {
                if ($changed['password']) {
                    $salt = \fast\Random::alnum();
                    $row->password = \app\common\library\Auth::instance()->getEncryptPassword($changed['password'], $salt);
                    $row->salt = $salt;
                } else {
                    unset($row->password);
                }
            }
        });

        self::beforeUpdate(function ($row) {
            $changed = $row->getChangedData();
            //如果有修改密码
            if (isset($changed['password'])) {
                if ($changed['password']) {
                    $salt = \fast\Random::alnum();
                    $row->password = \app\common\library\Auth::instance()->getEncryptPassword($changed['password'], $salt);
                    $row->salt = $salt;
                } else {
                    unset($row->password);
                }
            }
        });


        self::beforeUpdate(function ($row) {
            $changedata = $row->getChangedData();
            $origin = $row->getOriginData();
            if (isset($changedata['money']) && (function_exists('bccomp') ? bccomp($changedata['money'], $origin['money'], 2) !== 0 : (double)$changedata['money'] !== (double)$origin['money'])) {
                MoneyLog::create(['user_id' => $row['id'], 'money' => $changedata['money'] - $origin['money'], 'before' => $origin['money'], 'after' => $changedata['money'], 'memo' => '管理员变更金额']);
            }
            if (isset($changedata['score']) && (int)$changedata['score'] !== (int)$origin['score']) {
                ScoreLog::create(['user_id' => $row['id'], 'score' => $changedata['score'] - $origin['score'], 'before' => $origin['score'], 'after' => $changedata['score'], 'memo' => '管理员变更积分']);
            }
        });
    }

    public function getGenderList()
    {
        return ['1' => __('Male'), '0' => __('Female')];
    }

    public function getStatusList()
    {
        return ['normal' => __('Normal'), 'hidden' => __('Hidden')];
    }

    public function getMemberType()
    {
        return ['tourist' => __('tourist'), 'TrialMember' => __('TrialMember'), 'member' => __('member')];
    }

    public function getPrevtimeTextAttr($value, $data)
    {
        $value = $value ? $value : ($data['prevtime'] ?? "");
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }

    public function getAvatarObsAttr($value, $data)
    {
        $value = '';
        if (!empty($data['avatar'])){
            $value = obsurl($data['avatar']);
        }
        return $value;
    }

    public function getLogintimeTextAttr($value, $data)
    {
        $value = $value ? $value : ($data['logintime'] ?? "");
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }

    public function getJointimeTextAttr($value, $data)
    {
        $value = $value ? $value : ($data['jointime'] ?? "");
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }

    protected function setPrevtimeAttr($value)
    {
        return $value && !is_numeric($value) ? strtotime($value) : $value;
    }

    protected function setLogintimeAttr($value)
    {
        return $value && !is_numeric($value) ? strtotime($value) : $value;
    }

    protected function setJointimeAttr($value)
    {
        return $value && !is_numeric($value) ? strtotime($value) : $value;
    }

    protected function setBirthdayAttr($value)
    {
        return $value ? $value : null;
    }

//    protected function setPeriodOfValidityAttr($value)
//    {
//        return $value ? (new DateTime($value))->getTimestamp() * 1000 : null;
//    }

    protected function getPeriodOfValidityAttr($value)
    {
        return $value ? date('Y-m-d H:i:s', ($value / 1000)) : null;
    }

    public function group()
    {
        return $this->belongsTo('UserGroup', 'group_id', 'id', [], 'LEFT')->setEagerlyType(0);
    }

    //通过用户模型获取用户的频道
    public function getUserChannels($user)
    {
        $rule = UserGroup::where('id', $user['group_id'])->value('rules');
        $rule = explode(',', $rule);
        return UserRule::whereIn('id', $rule)->column('column_id');
    }

    //生成4位唯一邀请码
    public function generateInviteCode()
    {
        $inviteCode = mt_rand(1000, 9999);
        //检测邀请码是否是唯一的
        $is_user = User::where('invitation_code',$inviteCode)->find();
        if ($is_user){
            $this->generateInviteCode();
        }else{
            return $inviteCode;
        }
    }

    //获取随机昵称
    public function getRandomnickname(){
        $nickname = '盘友' . mt_rand(10000, 99999);
        $user = User::where('nickname',$nickname)->count();
        if ($user){
            $this->getRandomnickname();
        }else{
            return $nickname;
        }
    }

    //获取软删除用户
    public static function getSoftDeleteUser($user_id){
        if (!$user_id){
            $user = [
                'id'=>$user_id,
                'username'=>'管理员',
                'nickname'=>'管理员',
                'avatar'=>'/img/default_user.jpg',
                'bio'=>'',
                'email'=>'',
            ];
        }else{
                $user = User::withTrashed()->where('id',$user_id)->field('id,username,nickname,avatar,bio,email')->find();
                if ($user){
                    $user = $user->toArray();
                } else {
                    $user = [
                        'id'=>$user_id,
                        'username'=>'管理员',
                        'nickname'=>'管理员',
                        'avatar'=>'/img/default_user.jpg',
                        'bio'=>'',
                        'email'=>'',
                    ];
                }
        }
        return $user;
    }

    //检测用户是否有权限访问当前分类,如果顶级分类允许访问则2级分类全部允许访问
    public function isChannelsPermission($user){
        $res = [
            'rule_column_id' => []
        ];
        $user = Db::name('user')->where('id',$user['id'])->find();

        //判断会员是否有效period_of_validity:过期时间毫秒|0=无效,1=长期有效,毫秒时间戳=有效时间
        $time = time() * 1000;

        if($user['period_of_validity'] == 0){
            return $res;
        }

        if ($user['period_of_validity'] > 1 && $user['period_of_validity'] < $time){
            return $res;
        }

        $rule_column_id = $this->getUserChannels($user);//得到全部可以访问的栏目id有顶级,有2级栏目的id)
        if (!$rule_column_id){
            return $res;
        }
        //通过权限表得到栏目表中对应的顶级id
//        $column_ids_1 = Channels::whereIn('id',$rule_column_id)->where('parent_id',0)->column('id') ?? [];
        $column_ids_1 = Channels::whereIn('id',$rule_column_id)->where('parent_id','<>',0)->column('id') ?? [];//直接获取用户拥有的二级分类的权限的Channels表id
        //通过顶级id在得到他们的2级id
//        $column_ids_2 = Channels::whereIn('parent_id',$column_ids_1)->column('id') ?? [];

        //将当前用户拥有的全部id合并含2级栏目
//        $merged_ids = array_merge($column_ids_1, $column_ids_2,$rule_column_id);

        sort($column_ids_1);
        $merged_ids = array_unique($column_ids_1);
        $merged_ids = array_filter($merged_ids);
        $res['rule_column_id'] = array_unique($merged_ids);//Channels表id

        //当前用户拥有权限的的全部栏目id(含顶级和2级栏目id)|默认空array|channels表中的id
        return $res;
    }
}
